/**
 @Description: vite基础配置
 @Document: https://cn.vitejs.dev/config.html vite官方中文文档
 @Document: https://terser.org/docs/api-reference#minify-options terserOptions配置文档
 */

import { resolve } from 'path'
import vue from '@vitejs/plugin-vue2'
import vueJsx from 'vite-plugin-jsx-vue2'
import { visualizer } from 'rollup-plugin-visualizer'
import Icons from 'unplugin-icons/vite'
import { loadEnv, splitVendorChunkPlugin } from 'vite'
import { createHtmlPlugin } from 'vite-plugin-html'
import Inspect from 'vite-plugin-inspect'
import viteCompression from 'vite-plugin-compression'
import { PROXY_PREFIX } from './global-constant'
import { EnumProxy } from './globalEnum'

/**
 * 获取vite env变量
 * @param mode 子项目vite导出的mode
 * @param pathSrc 子项目路径
 * @param target 要获取的env目标变量名
 * @returns {string}
 */
const getViteEnv = (mode, pathSrc, target) => {
  return loadEnv(mode, resolve(__dirname, './env'), 'VITE_')[target]
}
/**
 * vite通用基础配置
 * @param mode 子项目vite导出的mode
 * @param pathSrc 子项目路径
 * @returns {{cacheDir: string, logLevel: string, resolve: {extensions: string[]}, clearScreen: boolean, publicDir: string, envDir: string, base: string}}
 */
export const useBasic = (mode, pathSrc) => ({
  base: '/',
  publicDir: 'public', // default
  cacheDir: 'node_modules/.vite', // default
  envDir: resolve(pathSrc, './env'), // 环境变量的存储路径
  logLevel: 'info', // default
  clearScreen: false // 默认值为true。调试时设置为false，可以看到更多信息
})

/**
 * server选项的默认全局配置, 如有特殊需求扩展可在子项目中重写覆盖
 * @param params.port 启动端口号
 * @param params.target 代理的目标, 必须为EnumProxy中声明的值
 * @param params.rewrite 重写代理url
 * @param params.ws 是否为websocket
 * @param params.hmr 是否热刷新
 * @returns {{proxy: {'[PROXY_PREFIX]': {changeOrigin: boolean, ws: undefined, hmr: undefined, rewrite: undefined, target: string}}, port: number, host: string, open: boolean}}
 */
export const useServer = (params = {}) => {
  const { port = 8080, target = EnumProxy.DEV, rewrite, ws, hmr } = params
  return {
    port,
    proxy: {
      [PROXY_PREFIX]: {
        target,
        changeOrigin: true,
        rewrite,
        ws,
        hmr
      }
    },
    open: true,
    host: '0.0.0.0'
  }
}
/**
 * CSS配置
 */
export const useCss = () => ({
  scss: {
    // additionalData: '@import "./src/common/assets/style/variables.scss";'
    // TODO additionalData: '@import "@/style/variable.scss";'  在此引入所有项目通用的样式配置
  }
})

/**
 * 插件配置
 */
export const usePlugins = (pathSrc, mode) => {
  return [
    vue(),
    vueJsx(),
    Inspect(),
    viteCompression(),
    splitVendorChunkPlugin(),
    visualizer({
      open: true,
      gzipSize: true,
      brotliSize: true
    }),
    // 让unplugin-icons自动安装图标库
    Icons({
      autoInstall: true
    }),
    createHtmlPlugin({
      inject: {
        data: {
          // 将环境变量 VITE_APP_TITLE 赋值给 title 在html页面使用 title 获取系统标题
          title: getViteEnv(mode, pathSrc, 'VITE_APP_TITLE')
        }
      }
    })
  ]
}

/**
 * 构建配置
 * @param mode 子项目vite导出的mode
 * @param pathSrc 子项目路径
 * @param appName 子项目名称
 * @returns {{terserOptions: {compress: {drop_console: boolean, keep_infinity: boolean}}, minify: string, emptyOutDir: boolean, sourcemap: boolean, rollupOptions: {output: {chunkFileNames: string, manualChunks: ((function(*): (*|undefined))|*), entryFileNames: string, assetFileNames: ((function(*): (string))|*)}}, assetsDir: string, reportCompressedSize: boolean, commonjsOptions: {transformMixedEsModules: boolean}, cssCodeSplit: boolean, chunkSizeWarningLimit: number, outDir: string, target: string}}
 */
export const useBuild = (mode, pathSrc, appName) => {
  const buildEnv = getViteEnv(mode, pathSrc, 'VITE_APP_ENV_NAME')
  return {
    outDir: resolve(__dirname, 'dist', appName),
    assetsDir: 'static',
    emptyOutDir: false,
    target: 'esnext', // default
    cssCodeSplit: true, // 启用/禁用 CSS 代码拆分
    sourcemap: !['production'].includes(buildEnv), // default
    // 最小化混淆。terser速度慢、文件体积小；esbuild速度快、文件体积大
    minify: 'terser',
    terserOptions: {
      compress: {
        keep_infinity: true,
        // 去除打印
        drop_console: false
      }
    },
    // 启用/禁用 gzip 压缩大小报告 设置为false，提高构建性能
    reportCompressedSize: false,
    // chunk 大小警告的限制（以 kbs 为单位）。
    chunkSizeWarningLimit: 500,
    commonjsOptions: {
      transformMixedEsModules: true
    },
    rollupOptions: {
      output: {
        manualChunks: (path) => {
          if (path.includes('node_modules')) {
            return path.toString().split('node_modules/')[1].split('/')[0].toString()
          }
        },
        entryFileNames: '[name]-[hash].js',
        chunkFileNames: 'js/[name]-[hash].js',
        assetFileNames: (info) => {
          const { name } = info
          const fileExt = name.substring(name.lastIndexOf('.'))
          if (fileExt === '.css') {
            return 'css/[name]-[hash].[ext]'
          }
          return 'assets/[name]-[hash].[ext]'
        }
      }
    }
  }
}
